﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Biza.Core.Bussiness
{
    /// <summary>
    /// 班组、班次计算器
    /// </summary>
    internal class ShiftCalculator
    {
        #region 默认初始化参数
        private const string FT_DATE = "yyyy-MM-dd";
        private const string FT_DATETIME = "yyyy-MM-dd HH:mm:ss";
        private DateTime _startTime = DateTime.Parse("2011-3-21 8:00:00");
        private TimeSpan _shiftInterval = new TimeSpan(8, 0, 0);
        private string[] _groupCycle = new string[] {  
            "甲班","乙班","丙班",
            "甲班","乙班","丙班",
            "丁班","甲班","乙班",
            "丁班","甲班","乙班",
            "丙班","丁班","甲班",
            "丙班","丁班","甲班",
            "乙班","丙班","丁班",
            "乙班","丙班","丁班" };
        private string[] _shiftCycle = new string[] { "白班", "中班", "夜班" };

        #endregion

        /// <summary>
        /// 排班开始时间
        /// </summary>
        public DateTime StartTime
        {
            get { return _startTime; }
            set { _startTime = value; }
        }
        /// <summary>
        /// 班组循环规则
        /// </summary>
        public string[] GroupCycle
        {
            get { return _groupCycle; }
            set { _groupCycle = value; }
        }
        /// <summary>
        /// 班次循环规则
        /// </summary>        
        public string[] ShiftCycle
        {
            get { return _shiftCycle; }
            set { _shiftCycle = value; }
        }
        /// <summary>
        /// 换班间隔
        /// </summary>
        public TimeSpan ShiftInterval
        {
            get { return _shiftInterval; }
            set { _shiftInterval = value; }
        }


        /// <summary>
        /// 使用默认规则初始化计算器
        /// </summary>
        public ShiftCalculator()
        {
        }
        /// <summary>
        /// 使用指定的参数初始化计算器
        /// </summary>
        /// <param name="startTime">排班开始时间</param>
        /// <param name="interval">换班间隔时间</param>
        /// <param name="groups">班组换班规则</param>
        /// <param name="shifts">班次换班规则</param>
        public ShiftCalculator(DateTime startTime, TimeSpan interval, string[] groups, string[] shifts)
        {
            this._startTime = startTime;
            this._shiftInterval = interval;
            if (groups.Length > 0)
            {
                this._groupCycle = groups;
            }
            if (shifts.Length > 0)
            {
                this._shiftCycle = shifts;
            }
        }


        /// <summary>
        /// 获取指定时间的班组
        /// </summary>
        /// <param name="current">指定时间</param>
        /// <returns>班组</returns>
        public string getGroup(DateTime current)
        {
            while (current < StartTime)
            {
                StartTime = StartTime - TimeSpan.FromSeconds(ShiftInterval.TotalSeconds * GroupCycle.Length);
            }
            double index = Math.Truncate((current - StartTime).TotalSeconds % (ShiftInterval.TotalSeconds * GroupCycle.Length) / ShiftInterval.TotalSeconds);
            return GroupCycle[(int)index];
        }
        /// <summary>
        /// 获取指定时间的班次
        /// </summary>
        /// <param name="current">指定时间</param>
        /// <returns>班次</returns>
        public string getShift(DateTime current)
        {
            while (current < StartTime)
            {
                StartTime = StartTime - TimeSpan.FromSeconds(ShiftInterval.TotalSeconds * ShiftCycle.Length);
            }
            double index = Math.Truncate((current - StartTime).TotalSeconds % (ShiftInterval.TotalSeconds * ShiftCycle.Length) / ShiftInterval.TotalSeconds);
            return ShiftCycle[(int)index];
        }
        /// <summary>
        /// 获取生产日期
        /// </summary>
        /// <param name="current">当前日期</param>
        /// <returns>生产日期</returns>
        public string getShiftDate(DateTime current)
        {
            var start1 = current.Date.AddDays(-1) + StartTime.TimeOfDay;
            var start2 = start1.AddHours(8);

            while (true)
            {
                if (current >= start1 && current < start2) break;

                start1 = start1.AddHours(8);
                start2 = start2.AddHours(8);
            }

            //理论：
            //如果一个班跨天，则认为该班次的绝大数时间的天为生产天
            var t1 = (start2 - start2.Date).TotalSeconds;
            var t2 = (start2.Date - start1).TotalSeconds;
            var dt = t2 > t1 ? start1.Date : start2.Date;

            return dt.ToString(FT_DATE);
        }
        /// <summary>
        /// 获取当班开始时间
        /// </summary>
        /// <param name="date">日期</param>
        /// <param name="shift">班次</param>
        /// <returns></returns>
        public string getShiftStartTime(string date, string shift)
        {
            var current = DateTime.Parse(date);
            var start = current.Date.AddDays(-1) + StartTime.TimeOfDay;

            while (true)
            {
                if (getShiftDate(start).Equals(date)
                    && getShift(start).Equals(shift)) break;
                start = start.AddHours(8);
            }

            return start.ToString(FT_DATETIME);
        }
    }
}
